// --------------------------------------------------------------------------------------------------------------------
// <copyright file="JFreeFrameLoader.cs" company="Jarno Burger / Dennis de Bruijn">
//   Jarno Burger / Dennis de Bruijn
// </copyright>
// <summary>
//   Defines the JFreeFrameLoader type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace TestProject
{
    using System;
    using System.Diagnostics;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Globalization;
    using System.IO;
    using System.Windows.Forms;

    using ManagedFreeFrame;
    using ManagedFreeFrame.Enum;

    internal sealed partial class FreeFrameLoader : Form
    {
        #region declare
        private bool _breakLoop;

        private Stopwatch _w;

        private bool _drawing;

        private int _count;

        private float _lastTIme;

        private FreeFrame _freeFrame;
        #endregion

        #region initialize

        /// <summary>
        ///   Initializes a new instance of the <see cref = "FreeFrameLoader" /> class.
        /// </summary>
        internal FreeFrameLoader()
        {
            this.InitializeComponent();
            this.FormClosing += this.OnMyFormClosing;
        }

        private void OnMyFormClosing(object sender, FormClosingEventArgs e)
        {
            this._breakLoop = true;
        }

        #endregion

        /// <summary>
        ///   Handles the Click event of the BtnOpenDll control.
        /// </summary>
        /// <param name = "sender">The source of the event.</param>
        /// <param name = "e">The <see cref = "System.EventArgs" /> instance containing the event data.</param>
        private void BtnOpenDllClick(object sender, EventArgs e)
        {
            this._breakLoop = true;
            if (this._freeFrame != null && this._freeFrame.Initialized)
            {
                this._freeFrame.DeInstantiate();
                this._freeFrame.DeInitialize();
            }

            var path = Path.GetDirectoryName(Application.ExecutablePath);
            var dialog = new OpenFileDialog
                             {           
                                 InitialDirectory = path,
                                 Filter = "freeframe dll files (*.dll)|*.dll",
                                 Title = "Select a text file",
                             };

            if (dialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            this.textBoxUrl.Text = dialog.FileName;

            this._freeFrame = new FreeFrame(new FileInfo(this.textBoxUrl.Text));

            // adresses
            this.textBoxLibaryAdress.Text = this._freeFrame.LibaryPointer.ToString();
            this.textBoxPlugMainAdress.Text = this._freeFrame.PlugMainPointer.ToString();

            // plugin info structure
            this.textBoxMajorVersion.Text = this._freeFrame.MajorVersion;
            this.textBoxMinorVersion.Text = this._freeFrame.MinorVersion;
            this.textBoxUniqueId.Text = this._freeFrame.UniqueID;
            this.textBox1PluginName.Text = this._freeFrame.PluginName;
            this.textBoxPluginType.Text = this._freeFrame.PluginType.ToString();

            // plugin capabilities
            this.checkBox16Bit.Checked = this._freeFrame.Support16Bit;
            this.checkBox24Bit.Checked = this._freeFrame.Support24Bit;
            this.checkBox32Bit.Checked = this._freeFrame.Support32Bit;
            this.checkBoxFrameCopy.Checked = this._freeFrame.SupportProcessFrameCopy;
            this.textBoxMinNumFrames.Text = 
                this._freeFrame.SupportMinimumNumberOfFrames ?
                    this._freeFrame.SupportMinimumNumberOfFramesNeeded.ToString(CultureInfo.InvariantCulture) : 
                    "Not Supported";
            this.textBoxMaxNumFrames.Text =
                this._freeFrame.SupportMinimumNumberOfFrames ?
                    this._freeFrame.SupportMinimumNumberOfFramesNeeded.ToString(CultureInfo.InvariantCulture) :
                    "Not Supported";
            this.textBoxOptimizedFor.Text = this._freeFrame.OptimizedFor.ToString();

            // extend info structure
            this.textBoxPluginMajorVersion.Text = this._freeFrame.ExtPluginMajorVersion;
            this.textBoxPluginMinorVersion.Text = this._freeFrame.ExtPluginMinorVersion;
            this.textBoxDescription.Text = this._freeFrame.ExtDescription;
            this.textBoxAbout.Text = this._freeFrame.ExtAbout;
            this.textBoxExtendedDataSize.Text = this._freeFrame.ExtDataSize.ToString(CultureInfo.InvariantCulture);

            // parameters
            this.textBoxNumberOfParameters.Text = this._freeFrame.NumberOfParameters.ToString(CultureInfo.InvariantCulture);

            //' institiate the plugin
            var success = this._freeFrame.Instantiate((Bitmap)this.pictureBox1.Image);
            if (success == false)
            {
                this.Text = "The plugin does not support the format of the image in the PixtureBox";
                return;
            }
            this._freeFrame.GetParametersDisplay();
            this._freeFrame.GetParametersValue();
            this.PopulateListBox();
            this.ProcessFrame();

            // start the loop
            this._w = new Stopwatch();
            this._w.Start();

            this._breakLoop = false;
            while(this._breakLoop == false)
            {
                this.OnTick(null, null);
                Application.DoEvents();
            }
        }

        private void OnTick(object sender, EventArgs e)
        {
            this._count++;
            var currentTime = this._w.ElapsedMilliseconds;
            if (currentTime > this._lastTIme + 3000)
            {
                this.Text = ((int)(this._count / 3.0f)).ToString(CultureInfo.InvariantCulture) + " Frames/Second";
                this._count = 0;
                this._lastTIme = currentTime;
            }

            if (this._drawing) return;
            this._drawing = true;
            var random = new Random();
            for (var index = 0; index < this._freeFrame.Parameters.Count; index++)
            {
                var param = this._freeFrame.Parameters[index];
                if (param.ParameterType == ParameterType.Standard)
                {
                    var rnd = (float)random.NextDouble();
                    this._freeFrame.SetParamater((uint)index, rnd);
                }
            }

            this._freeFrame.GetParametersValue();
            this._freeFrame.GetParametersDisplay();
            this.ProcessFrame();
            this.PopulateListBox();

            this._drawing = false;
        }


        private void ProcessFrame()
        {
            var b = (Bitmap)this.pictureBox1.Image.Clone();
            var d = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, b.PixelFormat);
            this._freeFrame.ProcessFrame(d.Scan0);
            b.UnlockBits(d);
            pictureBox2.Image = b;
        }

        private void PopulateListBox()
        {
            ////return;
            ////this.listViewParameters.Items.Clear();

            ////foreach (var parameter in this._freeFrame.Parameters)
            ////{
            ////    var item = new ListViewItem { Text = parameter.Name };
            ////    item.SubItems.Add(parameter.ParameterType.ToString());
            ////    item.SubItems.Add(parameter.DefaultValue.ToString(CultureInfo.InvariantCulture));
            ////    item.SubItems.Add(parameter.Value.ToString(CultureInfo.InvariantCulture));
            ////    item.SubItems.Add(parameter.ParameterDisplay);
            ////    this.listViewParameters.Items.Add(item);
            ////}
        }
    }
}